/*
 * @Author: iy88 
 * @Date: 2020-02-17 11:11:46 
 * @Last Modified by: iy88
 * @Last Modified time: 2020-03-24 10:47:54
 */
const fs = require("fs");
const queryString = require("querystring");
const url = require('url');
const getClientIP = require('../tools/http/request/clientIP');
const color = require('chalk');
const getData = require('../tools/http/request/get_data');
const sendError = require('../tools/monitor/sendError');
const resError = require('../tools/http/response/core/response_error');
const Service = require('../lib/service');
module.exports = (config) => {
  console.log(color.green('create server successfully'));
  return {
    start: () => {
      const logger = require('../tools/monitor/logger');
      const protocol = require(config.server.protocol);
      const sv = (request, response) => {
        new Promise((resolve, reject) => {
          request.date = new Date().toJSON();
          request.ip = getClientIP(request);
          request.cookies = queryString.parse(request.headers.cookie);
          request.primaryUrl = request.url.slice(0);
          request.query = queryString.parse(url.parse(request.url).query);
          request.url = decodeURI(url.parse(request.url).pathname);
          request.method === 'GET' ? resolve() : reject();
        }).then(
            //method is GET
            () => {
              new Service(({request: request, response: response, public: config.server.public})).static();
            }
            //method isn't GET
            , () => {
              getData(request, (data) => {
                request.primaryData = data;
                request.data = queryString.parse(data);
                new Service(({request: request, response: response})).API();
              })
            }
        ).catch((error) => {
          resError(response, 500, (error, statusCode) => {
            //TODO check status & log request and response
          })
        })
      };
      if (config.server.protocol === 'http') {
        protocol.createServer(sv).listen(config.server.port, config.server.host, () => {
          console.log(color.green(`start server at host: ${config.server.host}, port: ${config.server.port}, protocol: ${config.server.protocol}, static page path: ${config.server.public}, successfully\nvisit at ${config.server.protocol}://${config.server.host}:${config.server.port}/`));
        });
      } else if (config.server.protocol === 'https') {
        const key = fs.readFileSync('../keys/key.pem');
        const cert = fs.readFileSync('../keys/cert.pem');
        const options = {
          key: key,
          cert: cert
        };
        protocol.createServer(options, sv).listen(config.server.port, config.server.host, () => {
          console.log(color.green(`start server at host: ${config.server.host}, port: ${config.server.port}, protocol: ${config.server.protocol}, static page path: ${config.server.public}, successfully\nvisit at ${config.server.protocol}://${config.server.host}:${config.server.port}/`));
        });
      } else {
        console.error('protocol error');
      }
    }
  };
};